package register

import (
	"fmt"
	"github.com/nacos-group/nacos-sdk-go/v2/clients"
	"github.com/nacos-group/nacos-sdk-go/v2/clients/naming_client"
	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
	"github.com/nacos-group/nacos-sdk-go/v2/vo"
)

type NacosConfig struct {
	TimeOut      uint64
	LogLevel     string
	NamespaceId  string
	ServerConfig []constant.ServerConfig
}

var DefaultNacosConfig = NacosConfig{
	ServerConfig: []constant.ServerConfig{
		{
			IpAddr:      "127.0.0.1",
			ContextPath: "/nacos",
			Port:        8859,
			Scheme:      "http",
		},
	},
	LogLevel:    "debug",
	NamespaceId: "",
	TimeOut:     5000,
}

func CreateNameClient(config NacosConfig) (naming_client.INamingClient, error) {
	clientConfig := *constant.NewClientConfig(
		constant.WithNamespaceId(config.NamespaceId), //When namespace is public, fill in the blank string here.
		constant.WithTimeoutMs(config.TimeOut),
		constant.WithNotLoadCacheAtStart(true),
		constant.WithLogLevel(config.LogLevel),
	)

	namingClient, err := clients.NewNamingClient(
		vo.NacosClientParam{
			ClientConfig:  &clientConfig,
			ServerConfigs: config.ServerConfig,
		},
	)
	return namingClient, err
}

type NacosServiceConfig struct {
	Ip          string
	Port        uint64
	ServiceName string
	ClusterName string
	GroupName   string
}

func RegisterService(namingClient naming_client.INamingClient, config NacosServiceConfig) (bool, error) {

	success, err := namingClient.RegisterInstance(vo.RegisterInstanceParam{
		Ip:          config.Ip,
		Port:        config.Port,
		ServiceName: config.ServiceName,
		Weight:      10,
		Enable:      true,
		Healthy:     true,
		Ephemeral:   true,
		Metadata:    map[string]string{"idc": "shanghai"},
		ClusterName: config.ClusterName, // default value is DEFAULT
		GroupName:   config.GroupName,   // default value is DEFAULT_GROUP
	})

	return success, err

}

func GetInstance(client naming_client.INamingClient, serviceName string) (string, uint64, error) {
	instance, err := client.SelectOneHealthyInstance(vo.SelectOneHealthInstanceParam{
		ServiceName: serviceName,
		//GroupName:   c.option.serviceConfig.GroupName,
		//Clusters:    []string{c.option.serviceConfig.ClusterName},
	})
	if err != nil {
		return "", uint64(0), err
	}
	return instance.Ip, instance.Port, nil
}

type MsNacosRegister struct {
	client naming_client.INamingClient
}

func (m *MsNacosRegister) CreateCli(option Option) error {
	//clientConfig := *constant.NewClientConfig(
	//	constant.WithNamespaceId(""), //When namespace is public, fill in the blank string here.
	//	constant.WithTimeoutMs(config.TimeOut),
	//	constant.WithNotLoadCacheAtStart(true),
	//	constant.WithLogLevel(config.LogLevel),
	//)
	namingClient, err := clients.NewNamingClient(
		vo.NacosClientParam{
			ClientConfig:  option.NacosClientConfig,
			ServerConfigs: option.NacosServerConfig,
		},
	)

	m.client = namingClient
	return err
}

func (m *MsNacosRegister) RegisterService(serviceName string, host string, port int) error {
	_, err := m.client.RegisterInstance(vo.RegisterInstanceParam{
		Ip:          host,
		Port:        uint64(port),
		ServiceName: serviceName,
		Weight:      10,
		Enable:      true,
		Healthy:     true,
		Ephemeral:   true,
		Metadata:    map[string]string{"idc": "shanghai"},
	})

	return err
}

func (m *MsNacosRegister) Close() error {
	return nil
}

func (m *MsNacosRegister) GetValue(serviceName string) (string, error) {
	instance, err := m.client.SelectOneHealthyInstance(vo.SelectOneHealthInstanceParam{
		ServiceName: serviceName,
		//GroupName:   c.option.serviceConfig.GroupName,
		//Clusters:    []string{c.option.serviceConfig.ClusterName},
	})
	if err != nil {
		return "", err
	}
	return fmt.Sprintf("%s:%d", instance.Ip, instance.Port), nil
}
